#pragma once

#include <iostream>
#include "Connection.hpp"
#include "Log.hpp"
#include "PackageParse.hpp"
using namespace log_ns;

class HandlerConnection
{
    const static int buffsize = 1024;

public:
    HandlerConnection(hander_t process) : _process(process)
    {
    }

    void HandlerRecver(Connection *conn)
    {
        errno = 0;
        while (true)
        {
            char buff[buffsize];
            int n = ::recv(conn->Sockfd(), buff, sizeof(buff) - 1, 0);
            if (n > 0)
            {
                buff[n] = 0;
                conn->AddInbuff(buff);
            }
            else
            {
                if (errno == EWOULDBLOCK)
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }

        // 一定将底层数据全部接受完毕，进行上层处理
        //std::cout << "inbuff内容: " << conn->Inbuffer() << std::endl;
        _process(conn);//报文分析
    }

    void HandlerSender(Connection *conn)
    {
        errno = 0;
        while(true)
        {
            ssize_t n = ::send(conn->Sockfd(),conn->Outbuffer().c_str(),conn->Outbuffer().size(),0);
            if(n > 0 )
            {
                conn->DiscardOutbuffer(n);
                if(conn->Outbuffer().empty())
                    break;
            }
            else if(n == 0)
            {
                return ;
            }
            else
            {
                if(errno == EWOULDBLOCK)
                {
                    //发送条件不满足
                    break;
                }
                else if(errno == EINTR)
                {
                    continue;
                }
                else 
                {
                    conn->_handler_excepter(conn);
                    return ;
                }
            }
        }

        //开启对写事件的关心
        if(!conn->Outbuffer().empty())
        {
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(),true,true);
        }
        else
        {
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(),true,false);
        }

    }

    void HandlerExcepter(Connection *conn)
    {
        conn->_R->DelConnection(conn->Sockfd());
    }

private:
    hander_t _process;
};